The following is from Azure Developer Training lab for AZ-203
Managed identities for Azure resources overview
Note: Managed identities for Azure resources is a feature of Azure Active Directory. Each of the Azure services that support managed identities for Azure resources are subject to their own timeline. Make sure you review the availability status of managedidentities for your resource and known issues before you begin.
A common challenge when building cloud applications is how to manage the credentials in your code for authenticating to cloud services. Keeping the credentials secure is an important task. Ideally, the credentials never appear on developer workstations andaren’t checked into source control. Azure Key Vault provides a way to securely store credentials, secrets, and other keys, but your code has to authenticate to Key Vault to retrieve them.
The managed identities for Azure resources feature in Azure Active Directory (Azure AD) solves this problem. The feature provides Azure services with an automatically managed identity in Azure AD. You can use the identity to authenticate to any service thatsupports Azure AD authentication, including Key Vault, without any credentials in your code.
The managed identities for Azure resources feature is free with Azure AD for Azure subscriptions. There’s no additional cost.
Note: Managed identities for Azure resources is the new name for the service formerly known as Managed Service Identity (MSI).
Terminology
The following terms are used throughout the managed identities for Azure resources documentation set:
- Client id – a unique identifier generated by Azure AD that is tied to an application and service principal during its initial provisioning.
- Principal id – the object id of the service principal object for your managed identity that is used to grant role based access to an Azure resource.
- Azure Instance Metadata Service (IMDS) – a REST Endpoint accessible to all IaaS VMs created via the Azure Resource Manager. The endpoint is available at a well-known non-routable IP address (169.254.169.254) that can be accessed only from withinthe VM.
How the managed identities for Azure resources works
There are two types of managed identities:
- A system-assigned managed identity is enabled directly on an Azure service instance. When the identity is enabled, Azure creates an identity for the instance in the Azure AD tenant that’s trusted by the subscription of the instance. After the identity is created,the credentials are provisioned onto the instance. The lifecycle of a system-assigned identity is directly tied to the Azure service instance that it’s enabled on. If the instance is deleted, Azure automatically cleans up the credentials and the identity in Azure AD.
- A user-assigned managed identity is created as a standalone Azure resource. Through a create process, Azure creates an identity in the Azure AD tenant that’s trusted by the subscription in use. After the identity is created, the identity can be assigned to oneor more Azure service instances. The lifecycle of a user-assigned identity is managed separately from the lifecycle of the Azure service instances to which it’s assigned.
Your code can use a managed identity to request access tokens for services that support Azure AD authentication. Azure takes care of rolling the credentials that are used by the service instance.
The following diagram shows how managed service identities work with Azure virtual machines (VMs):
How a system-assigned managed identity works with an Azure VM
- Azure Resource Manager receives a request to enable the system-assigned managed identity on a VM.
- Azure Resource Manager creates a service principal in Azure AD for the identity of the VM. The service principal is created in the Azure AD tenant that’s trusted by the subscription.
- Azure Resource Manager configures the identity on the VM:
- Updates the Azure Instance Metadata Service identity endpoint with the service principal client ID and certificate.
- Provisions the VM extension (planned for deprecation in January 2019), and adds the service principal client ID and certificate. (This step is planned for deprecation.)
- After the VM has an identity, use the service principal information to grant the VM access to Azure resources. To call Azure Resource Manager, use role-based access control (RBAC) in Azure AD to assign the appropriate role to the VM service principal. Tocall Key Vault, grant your code access to the specific secret or key in Key Vault.
- Your code that’s running on the VM can request a token from two endpoints that are accessible only from within the VM:
- Azure Instance Metadata Service identity endpoint (recommended): http://169.254.169.254/metadata/identity/oauth2/token
- The resource parameter specifies the service to which the token is sent. To authenticate to Azure Resource Manager, use resource=https://management.azure.com/.
- API version parameter specifies the IMDS version, use api-version=2018-02-01 or greater.
- VM extension endpoint (planned for deprecation in January 2019): http://localhost:50342/oauth2/token
- The resource parameter specifies the service to which the token is sent. To authenticate to Azure Resource Manager, use resource=https://management.azure.com/.
- Azure Instance Metadata Service identity endpoint (recommended): http://169.254.169.254/metadata/identity/oauth2/token
- A call is made to Azure AD to request an access token (as specified in step 5) by using the client ID and certificate configured in step 3. Azure AD returns a JSON Web Token (JWT) access token.
- Your code sends the access token on a call to a service that supports Azure AD authentication.
How a user-assigned managed identity works with an Azure VM
- Azure Resource Manager receives a request to create a user-assigned managed identity.
- Azure Resource Manager creates a service principal in Azure AD for the user-assigned managed identity. The service principal is created in the Azure AD tenant that’s trusted by the subscription.
- Azure Resource Manager receives a request to configure the user-assigned managed identity on a VM:
- Updates the Azure Instance Metadata Service identity endpoint with the user-assigned managed identity service principal client ID and certificate.
- Provisions the VM extension, and adds the user-assigned managed identity service principal client ID and certificate. (This step is planned for deprecation.)
- After the user-assigned managed identity is created, use the service principal information to grant the identity access to Azure resources. To call Azure Resource Manager, use RBAC in Azure AD to assign the appropriate role to the service principal of theuser-assigned identity. To call Key Vault, grant your code access to the specific secret or key in Key Vault.Note: You can also do this step before step 3.
- Your code that’s running on the VM can request a token from two endpoints that are accessible only from within the VM:
- Azure Instance Metadata Service identity endpoint (recommended): http://169.254.169.254/metadata/identity/oauth2/token
- The resource parameter specifies the service to which the token is sent. To authenticate to Azure Resource Manager, use resource=https://management.azure.com/.
- The client ID parameter specifies the identity for which the token is requested. This value is required for disambiguation when more than one user-assigned identity is on a single VM.
- The API version parameter specifies the Azure Instance Metadata Service version. Use api-version=2018-02-01 or higher.
- VM extension endpoint (planned for deprecation in January 2019): http://localhost:50342/oauth2/token
- The resource parameter specifies the service to which the token is sent. To authenticate to Azure Resource Manager, use resource=https://management.azure.com/.
- The client ID parameter specifies the identity for which the token is requested. This value is required for disambiguation when more than one user-assigned identity is on a single VM.
- Azure Instance Metadata Service identity endpoint (recommended): http://169.254.169.254/metadata/identity/oauth2/token
- A call is made to Azure AD to request an access token (as specified in step 5) by using the client ID and certificate configured in step 3. Azure AD returns a JSON Web Token (JWT) access token.
- Your code sends the access token on a call to a service that supports Azure AD authentication.
Configure managed identities for Azure resources on an Azure VM using Azure CLI
In this article, you learn how to enable and disable system and user-assigned managed identities for an Azure Virtual Machine (VM), using the Azure CLI.
System-assigned managed identity
In this section, you learn how to enable and disable the system-assigned managed identity on an Azure VM using Azure CLI.
To create an Azure VM with the system-assigned managed identity enabled, your account needs the Virtual Machine Contributor role assignment. No additional Azure AD directory role assignments are required.
Enable system-assigned managed identity during creation of an Azure VM
- If you’re using the Azure CLI in a local console, first sign in to Azure using az login. Use an account that is associated with the Azure subscription under which you would like to deploy the VM:
az login
- Create a resource group for containment and deployment of your VM and its related resources, using az group create. You can skip this step if you already have resource group you would like to use instead:
az group create --name myResourceGroup --location westus
- Create a VM using az vm create. The following example creates a VM named myVM with a system-assigned managed identity, as requested by the –assign-identity parameter. The –admin-username and –admin-password parameters specify the administrative user name and password account for virtual machine sign-in. Update these values as appropriate for your environment:
az vm create --resource-group myResourceGroup --name myVM --image win2016datacenter --generate-ssh-keys --assign-identity --admin-username azure user --admin-password myPassword12
Enable system-assigned managed identity on an existing Azure VM
Sign in to Azure using an account that is associated with the Azure subscription that contains the VM. Use az vm with the identity assign command to enable to the system-assigned identity to an existing VM.
az vm identity assign -g myResourceGroup -n myVm
Disable system-assigned identity from an Azure VM
To disable system-assigned managed identity on a VM, your account needs the Virtual Machine Contributor role assignment. No additional Azure AD directory role assignments are required.
If you have a Virtual Machine that no longer needs the system-assigned identity, but still needs user-assigned identities, use the following command:
az vm update -n myVM -g myResourceGroup --set identity.type='UserAssigned'
If you have a virtual machine that no longer needs system-assigned identity and it has no user-assigned identities, use the following command:
Note: The value none is case sensitive. It must be lowercase.
az vm update -n myVM -g myResourceGroup --set identity.type="none"
To remove the managed identity for Azure resources VM extension (planned for deprecation in January 2019), user -n ManagedIdentityExtensionForWindows or -n ManagedIdentityExtensionForLinux switch (depending on the type ofVM):
az vm identity --resource-group myResourceGroup --vm-name myVm -n ManagedIdentityExtensionForWindows
User-assigned managed identity
In this section, you will learn how to add and remove a user-assigned managed identity from an Azure VM using Azure CLI.
To assign a user-assigned identity to a VM during its creation, your account needs the Virtual Machine Contributor and Managed Identity Operator role assignments. No additional Azure AD directory role assignments are required.
Important: When creating user assigned identities, only alphanumeric characters (0-9, a-z, A-Z) and the hyphen (-) are supported. Additionally, the name should be limited to 24 characters in length for the assignment to VM/VMSS to work properly. Check backfor updates. For more information, see FAQs and known issues.
Assign a user-assigned managed identity during the creation of an Azure VM
- You can skip this step if you already have a resource group you would like to use. Create a resource group for containment and deployment of your user-assigned managed identity, using az group create. Be sure to replace the <RESOURCE GROUP>and <LOCATION> parameter values with your own values. :
az group create --name <RESOURCE GROUP> --location <LOCATION>
- Create a user-assigned managed identity using az identity create. The -g parameter specifies the resource group where the user-assigned managed identity is created, and the -n parameter specifies its name.
az identity create -g myResourceGroup -n myUserAssignedIdentity
The response contains details for the user-assigned managed identity created, similar to the following. The resource id value assigned to the user-assigned managed identity is used in the following step.
{ "clientId": "73444643-8088-4d70-9532-c3a0fdc190fz", "clientSecretUrl": "https://control-westcentralus.identity.azure.net/subscriptions/<SUBSCRIPTON ID>/resourcegroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<myUserAssignedIdentity>/credentials?tid=5678&oid=9012&aid=73444643-8088-4d70-9532-c3a0fdc190fz", "id": "/subscriptions/<SUBSCRIPTON ID>/resourcegroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>", "location": "westcentralus", "name": "<USER ASSIGNED IDENTITY NAME>", "principalId": "e5fdfdc1-ed84-4d48-8551-fe9fb9dedfll", "resourceGroup": "<RESOURCE GROUP>", "tags": {}, "tenantId": "733a8f0e-ec41-4e69-8ad8-971fc4b533bl", "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }
- Create a VM using az vm create. The following example creates a VM associated with the new user-assigned identity, as specified by the –assign-identity parameter. Be sure to replace the <RESOURCE GROUP>, <VM NAME>, <USERNAME>, <PASSWORD>, and <USER ASSIGNED IDENTITY NAME> parameter values with your own values.
az vm create --resource-group <RESOURCE GROUP> --name <VM NAME> --image UbuntuLTS --admin-username <USER NAME> --admin-password <PASSWORD> --assign-identity <USER ASSIGNED IDENTITY NAME>
Assign a user-assigned managed identity to an existing Azure VM
- Create a user-assigned identity using az identity create. The -g parameter specifies the resource group where the user-assigned identity is created, and the -n parameter specifies its name. Be sure to replace the <RESOURCE GROUP> and<USER ASSIGNED IDENTITY NAME> parameter values with your own values:
az identity create -g <RESOURCE GROUP> -n <USER ASSIGNED IDENTITY NAME>
The response contains details for the user-assigned managed identity created, similar to the following.
{ "clientId": "73444643-8088-4d70-9532-c3a0fdc190fz", "clientSecretUrl": "https://control-westcentralus.identity.azure.net/subscriptions/<SUBSCRIPTON ID>/resourcegroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>/credentials?tid=5678&oid=9012&aid=73444643-8088-4d70-9532-c3a0fdc190fz", "id": "/subscriptions/<SUBSCRIPTON ID>/resourcegroups/<RESOURCE GROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<USER ASSIGNED IDENTITY NAME>", "location": "westcentralus", "name": "<USER ASSIGNED IDENTITY NAME>", "principalId": "e5fdfdc1-ed84-4d48-8551-fe9fb9dedfll", "resourceGroup": "<RESOURCE GROUP>", "tags": {}, "tenantId": "733a8f0e-ec41-4e69-8ad8-971fc4b533bl", "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }
- Assign the user-assigned identity to your VM using az vm identity assign. Be sure to replace the <RESOURCE GROUP> and <VM NAME> parameter values with your own values. The <USER ASSIGNED IDENTITY NAME> is the user-assigned managed identity’s resource name property, as created in the previous step:
az vm identity assign -g <RESOURCE GROUP> -n <VM NAME> --identities <USER ASSIGNED IDENTITY>
Remove a user-assigned managed identity from an Azure VM
To remove a user-assigned identity to a VM, your account needs the Virtual Machine Contributor role assignment.
If this is the only user-assigned managed identity assigned to the virtual machine, UserAssigned will be removed from the identity type value. Be sure to replace the <RESOURCE GROUP> and <VM NAME> parameter values with your own values. The<USER ASSIGNED IDENTITY> will be the user-assigned identity’s name property, which can be found in the identity section of the virtual machine using az vm identity show:
az vm identity remove -g <RESOURCE GROUP> -n <VM NAME> --identities <USER ASSIGNED IDENTITY>
If your VM does not have a system-assigned managed identity and you want to remove all user-assigned identities from it, use the following command:
Note: The value none is case sensitive. It must be lowercase.
az vm update -n myVM -g myResourceGroup --set identity.type="none" identity.userAssignedIdentities=null
If your VM has both system-assigned and user-assigned identities, you can remove all the user-assigned identities by switching to use only system-assigned by using the following command:
az vm update -n myVM -g myResourceGroup --set identity.type='SystemAssigned' identity.userAssignedIdentities=null
How to use managed identities for Azure resources on an Azure VM to acquire an access token
A client application can request managed identities for Azure resources app-only access token for accessing a given resource. The token is based on the managed identities for Azure resources service principal. As such, there is no need for the client to registeritself to obtain an access token under its own service principal. The token is suitable for use as a bearer token in service-to-service calls requiring client credentials.
Get a token using HTTP
The fundamental interface for acquiring an access token is based on REST, making it accessible to any client application running on the VM that can make HTTP REST calls. This is similar to the Azure AD programming model, except the client uses an endpointon the virtual machine (vs an Azure AD endpoint).
Sample request using the Azure Instance Metadata Service (IMDS) endpoint:
GET 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' HTTP/1.1 Metadata: true
Element | Description |
GET | The HTTP verb, indicating you want to retrieve data from the endpoint. In this case, an OAuth access token. |
http://169.254.169.254/metadata/identity/oauth2/token | The managed identities for Azure resources endpoint for the Instance Metadata Service. |
api-version | A query string parameter, indicating the API version for the IMDS endpoint. Please use API version 2018-02-01 or greater. |
resource | A query string parameter, indicating the App ID URI of the target resource. It also appears in the aud (audience) claim of theissued token. This example requests a token to access Azure Resource Manager, which has an App ID URI ofhttps://management.azure.com/. |
Metadata | An HTTP request header field, required by managed identities for Azure resources as a mitigation against Server Side RequestForgery (SSRF) attack. This value must be set to “true”, in all lower case. |
object_id | (Optional) A query string parameter, indicating the object_id of the managed identity you would like the token for. Required, ifyour VM has multiple user-assigned managed identities. |
client_id | (Optional) A query string parameter, indicating the client_id of the managed identity you would like the token for. Required, ifyour VM has multiple user-assigned managed identities. |
Sample response:
HTTP/1.1 200 OK Content-Type: application/json { "access_token": "eyJ0eXAi...", "refresh_token": "", "expires_in": "3599", "expires_on": "1506484173", "not_before": "1506480273", "resource": "https://management.azure.com/", "token_type": "Bearer" }
Element | Description |
access_token | The requested access token. When calling a secured REST API, the token is embedded in the Authorization request headerfield as a “bearer” token, allowing the API to authenticate the caller. |
refresh_token | Not used by managed identities for Azure resources. |
expires_in | The number of seconds the access token continues to be valid, before expiring, from time of issuance. Time of issuance can befound in the token’s iat claim. |
expires_on | The timespan when the access token expires. The date is represented as the number of seconds from “1970-01-01T0:0:0Z UTC” (corresponds to the token’s exp claim). |
not_before | The timespan when the access token takes effect, and can be accepted. The date is represented as the number of seconds from“1970-01-01T0:0:0Z UTC” (corresponds to the token’s nbf claim). |
resource | The resource the access token was requested for, which matches the resource query string parameter of the request. |
token_type | The type of token, which is a “Bearer” access token, which means the resource can give access to the bearer of this token. |
Token caching
While the managed identities for Azure resources subsystem being used (IMDS/managed identities for Azure resources VM Extension) does cache tokens, we also recommend to implement token caching in your code. As a result, you should prepare for scenarioswhere the resource indicates that the token is expired.
On-the-wire calls to Azure AD result only when:
- cache miss occurs due to no token in the managed identities for Azure resources subsystem cache
- the cached token is expired
Error handling
The managed identities for Azure resources endpoint signals errors via the status code field of the HTTP response message header, as either 4xx or 5xx errors:
Status Code | Error Reason | How To Handle |
404 Not found. | IMDS endpoint is updating. | Retry with Expontential Backoff. See guidance below. |
429 Too many requests. | IMDS Throttle limit reached. | Retry with Exponential Backoff. See guidance below. |
4xx Error in request. | One or more of the request parameters was incorrect. | Do not retry. Examine the error details for more information. 4xx errors are design-time errors. |
5xx Transient error from service. | The managed identities for Azure resources sub-system or Azure Active Directoryreturned a transient error. | It is safe to retry after waiting for at least 1 second. If you retry too quickly or toooften, IMDS and/or Azure AD may return a rate limit error (429). |
timeout | IMDS endpoint is updating. | Retry with Expontential Backoff. See guidance below. |
If an error occurs, the corresponding HTTP response body contains JSON with the error details:
Element | Description |
error | Error identifier. |
error_description | Verbose description of error. Error descriptions can change at any time. Do not write code that branches based on values in theerror description. |
HTTP response reference
This section documents the possible error responses. A “200 OK” status is a successful response, and the access token is contained in the response body JSON, in the access_token element.
Status code | Error | Error Description | Solution |
400 Bad Request | invalid_resource | AADSTS50001: The application named <URI> was not foundin the tenant named <TENANT-ID>. This can happen if theapplication has not been installed by the administrator of thetenant or consented to by any user in the tenant. You mighthave sent your authentication request to the wrong tenant.\ | (Linux only) |
400 Bad Request | bad_request_102 | Required metadata header not specified | Either the Metadata request header field is missing fromyour request, or is formatted incorrectly. The value must bespecified as true, in all lower case. See the “Samplerequest” in the preceding REST section for an example. |
401 Unauthorized | unknown_source | Unknown Source <URI> | Verify that your HTTP GET request URI is formatted correctly.The scheme:host/resource-path portion must bespecified ashttp://localhost:50342/oauth2/token. |
invalid_request | The request is missing a required parameter, includes aninvalid parameter value, includes a parameter more thanonce, or is otherwise malformed. | ||
unauthorized_client | The client is not authorized to request an access token usingthis method. | Caused by a request that didn’t use local loopback to call theextension, or on a VM that doesn’t have managed identities forAzure resources configured correctly. | |
access_denied | The resource owner or authorization server denied therequest. | ||
unsupported_response_type | The authorization server does not support obtaining an accesstoken using this method. | ||
invalid_scope | The requested scope is invalid, unknown, or malformed. | ||
500 Internal server error | unknown | Failed to retrieve token from the Active directory. For detailssee logs in <file path> | Verify that managed identities for Azure resources has beenenabled on the VM.
Also verify that your HTTP GET request URI is formattedcorrectly, particularly the resource URI specified in the querystring. |
Retry guidance
It is recommended to retry if you receive a 404, 429, or 5xx error code.
Throttling limits apply to the number of calls made to the IMDS endpoint. When the throttling threshold is exceeded, IMDS endpoint limits any further requests while the throttle is in effect. During this period, the IMDS endpoint will return the HTTP status code429 (“Too many requests”), and the requests fail.
For retry, we recommend the following strategy:
Retry strategy | Settings | Values | How it works |
ExponentialBackoff | Retry count
Min back-off Max back-off Delta back-off First fast retry |
5
0 sec 60 sec 2 sec false |
Attempt 1 – delay 0 sec
Attempt 2 – delay ~2 sec Attempt 3 – delay ~6 sec Attempt 4 – delay ~14 sec Attempt 5 – delay ~30 sec |
Assign a managed identity access to a resource using Azure CLI
Once you’ve configured an Azure resource with a managed identity, you can give the managed identity access to another resource, just like any security principal. This example shows you how to give an Azure virtual machine or virtual machine scale set’s managed identity access to an Azure storage account using Azure CLI.
Use RBAC to assign a managed identity access to another resource
After you’ve enabled managed identity on an Azure resource, such as an Azure virtual machine:
- If you’re using the Azure CLI in a local console, first sign in to Azure using az login. Use an account that is associated with the Azure subscription under which you would like to deploy the VM:
az login
- In this example, we are giving an Azure virtual machine access to a storage account. First we use az resource list to get the service principal for the virtual machine named myVM:
spID=$(az resource list -n myVM --query [*].identity.principalId --out tsv)
For an Azure virtual machine scale set, the command is the same except here, you get the service principal for the virtual machine scale set named DevTestVMSS:
spID=$(az resource list -n DevTestVMSS --query [*].identity.principalId --out tsv)
- Once you have the service principal ID, use az role assignment create to give the virtual machine Reader access to a storage account called myStorageAcct:
az role assignment create --assignee $spID --role 'Reader' --scope /subscriptions/<mySubscriptionID>/resourceGroups/<myResourceGroup>/providers/Microsoft.Storage/storageAccounts/myStorageAcct
Using Certificates, Tokens
Certificate-based Authentication
Client certificate authentication enables each web-based client to establish its identity to a server by using a digital certificate, which provides additional security for user authentication. In the context of Microsoft Azure, certificate-based authentication enablesyou to be authenticated by Azure Active Directory (Azure AD) with a client certificate on a Windows or mobile device when connecting to different services, including (but not limited to):
- Custom services authored by your organization
- Microsoft SharePoint Online
- Microsoft Office 365 (or Microsoft Exchange)
- Skype for Business
- Azure API Management
- Third-party services deployed in your organization
Helping to secure back-end services
Certificate-based authentication can be useful in scenarios where your organization has multiple front-end applications communicating with back-end services. Traditionally, the certificates are installed on each server, and the machines trust each other aftervalidating certificates. This same traditional structure can be used for infrastructure in Azure.
With cloud-native applications, you can use certificates to help secure connections in hybrid scenarios. For example, you can restrict access to your Azure web app by enabling different types of authentication for it. One way to do so is to authenticate using a client certificate when the request is over Transport Layer Security (TLS) / Secure Sockets Layer (SSL). This mechanism is called TLS mutual authentication or client certificate authentication. As another example, API Management allows more-secure access to the back-end service of an API using client certificates.
Legacy authentication methods
Most cloud-native applications will use a token-based or certificate-based authentication scheme. However, many applications are migrated to the cloud or connected to the cloud in a hybrid way. These applications may already have significant developer investment that makes changing the authentication scheme a significant resource challenge.
Forms-based authentication
Forms authentication uses an HTML form to send the user’s credentials to the server. It is not an internet standard. Forms authentication is appropriate only for web APIs that are called from a web application so that the user can interact with the HTML form.Forms authentication does have a few disadvantages, including:
- It requires a browser client to use the HTML form.
- It requires measures to prevent cross-site request forgery (CSRF).
- User credentials are sent in plaintext as part of an HTTP request.
The most common workflow for forms-based authentication works like this:
- The client requests a resource that requires authentication.
- If the user is not authenticated, the server returns HTTP 302 (Found) and redirects to a login page.
- The user enters credentials and submits the form.
- The server returns another HTTP 302 that redirects back to the original URI. This response includes an authentication cookie.
- The client requests the resource again. The request includes the authentication cookie, so the server grants the request.
In the context of Azure, many applications using forms-based authentication are legacy applications that were shifted to Azure without being refactored or rewritten. Using Microsoft ASP.NET forms authentication as an example, migration to the cloud would require only changing the connection string for the database that is used to store the forms authentication data. Using Azure as an example, you can migrate the identity database from Microsoft SQL Server to Azure SQL Database to continue to use forms-based authentication in Azure.
Windows-based authentication
Integrated Windows authentication enables users to log in with their Windows credentials using Kerberos or NTLM. The client sends credentials in the Authorization header. Windows authentication is best suited for an intranet environment. Windows authentication does have a few disadvantages, including:
- It’s difficult to use in internet applications without exposing the entire user directory.
- It can’t be used in Bring Your Own Device (BYOD) scenarios.
- It Requires Kerberos or Integrated Windows Authentication (NTLM) support in the client browser or device.
- The client must be joined to the Active Directory Domain.
In a hybrid deployment, it is common to see the main responsibilities of identity moved from on-premises Active Directory to Azure AD. The on-premises Active Directory servers remain as a way to manage physical machines and to enable simple Windows-based authentication. Azure AD Connect is used to synchronize identity from Azure AD to the on-premises Active Directory servers.
Token-based authentication
Claims-based authentication in .NET
Historically, ASP.NET applications used forms authentication to solve member requirements that were common in the early 2000s. These requirements revolved mostly around authoring login forms and managing a SQL Server database for user names, passwords, and profile data. Today, there is a much broader array of data storage options for web applications, and most developers want to enable their sites to use social identity providers for authentication and authorization functionality. While it’s possible to implement these new features in a database, it is unnecessarily difficult when many identity providers implement storage, tokens, and claims already.
ASP.NET Identity is a unified identity platform for ASP.NET applications that can be used across all flavors of ASP.NET and that can be used in web, phone, store, or hybrid applications. ASP.NET Identity implements two core features that makes it ideal for token-based authentication:
- ASP.NET Identity implements a provider model for logins. Today you may want to log in using a local Active Directory server, but tomorrow you may want to migrate to Azure AD. In ASP.NET Identity, you can simply add, remove, or replace providers. If your company decides to implement social network logins, you can keep adding providers or write your own providers without changing any other code in your application.
- ASP.NET Identity supports claims-based authentication, where the user’s identity is represented as a set of claims. Claims allow developers to be a lot more expressive in describing a user’s identity than roles allow. Whereas role membership is just aBoolean value (member or non-member), a claim can include rich information about the user’s identity and membership. Most social providers return metadata about the logged-in user as a series of claims.
App Service authentication and authorization
Azure App Service provides built-in authentication and authorization support, so you can sign in users and access data by writing minimal or no code in your app instance. The authentication and authorization module runs in the same sandbox as yourapplication code. When it’s enabled, every incoming HTTP request passes through it before being handled by your application code.
All AuthN/AuthZ logic, including cryptography for token validation and session management, executes in the worker sandbox and outside of the web app code. The module runs separately from your application code and is configured using app settings. Nosoftware development kits (SDKs), specific languages, or changes to your application code are required.
Identity information flows directly into the application code. For all language frameworks, App Service makes the user’s claims available to your code by injecting them into the request headers. For Microsoft .NET applications, App Service populatesClaimsPrincipal.Current with the authenticated user’s claims, so you can follow the standard .NET code pattern, including the [Authorize] attribute. Similarly, for PHP apps, App Service populates the _SERVER[‘REMOTE_USER’] variable.
App Service provides a built-in token store, which is a repository of tokens that are associated with the users of your web apps, APIs, or native mobile apps. You typically must write code to collect, store, and refresh these tokens in your application. With the tokenstore, you just retrieve the tokens when you need them and tell App Service to refresh them when they become invalid. When you enable authentication with any provider, this token store is immediately available to your app. The token information can be used inyour application code to perform tasks such as:
- Posting to the authenticated user’s Facebook timeline.
- Reading the user’s corporate data from the Azure AD Graph API or even from the Microsoft Graph.
Multi-factor authentication
When a user logs into an application, they typically provide a username and password. The password is provided by the user as a piece of evidence to the authentication system that the user is who they claim to be. The password is considered one factor provingthe user’s identity. A user could have other factors that proves their identity, such as:
- A physical badge from the company.
- Knowledge of the answers to security questions.
- A mobile device, registered with the company, that can receive notifications, phone calls, or SMS messages.
- Their physical appearance that can be captured by a camera device.
- Their fingerprint that could be captured by a biometric scanner.
Unfortunately, a single factor can potentially be compromised either intentionally or unintentionally. A badge can be stolen and used by an unauthorized party. During a robbery, someone could ask you to use your fingerprint on a device. A mobile company could accidentally send SMS messages to another device.
In security best practices, it is recommended to use two or more factors when authenticating users. This practice is referred to as multi-factor authentication. Using an enterprise as an example, the company could require employees to scan their badges and then enter their passwords as two factors of authentication. In the world of security, it is often recommended to have two of the following factors:
- Knowledge – Something that only the user knows (security questions, password, or PIN).
- Possession – Something that only the user has (corporate badge, mobile device, or security token).
- Inherence – Something that only the user is (fingerprint, face, voice, or iris).
The security of two-step verification lies in its layered approach. Compromising multiple authentication factors presents a significant challenge for attackers. Even if an attacker manages to learn the user’s password, it is useless without possession of the additional authentication method.
Multi-factor authentication with Azure AD
Azure Multi-Factor Authentication (MFA) is a two-step verification solution that is built in to Azure AD. Administrators can configure approved authentication methods to ensure that at least two factors are used while still keeping the sign-in process as streamlined as possible.
There are two ways to enable MFA:
- The first option is to enable each user for MFA. When users are enabled individually, they perform two-step verification each time they sign in. There are a few exceptions, such as when they sign in from trusted IP addresses or when the remembered devices feature is turned on.
- The second option is to set up a conditional access policy that requires two-step verification under certain conditions. This method uses the Azure AD Identity Protection risk policy to require two-step verification based only on the sign-in risk for all cloud applications.
Once MFA is enabled, administrators can choose which methods of authentication are available to users. Once users enroll, they must choose at least one method from the list that the administrator has enabled. These methods include:
Method | Description |
Call to phone | Places an automated voice call. The user answers the call and presses # on the phone keypad to authenticate. The phone number is not synchronized to on-premises Active Directory. |
Text message to phone | Sends a text message that contains a verification code. The user is prompted to enter the verification code into the sign-in interface. This process is called one-way SMS. Two-way SMS means that the user must text back a particular code. |
Notification through mobile app | Sends a push notification to your phone or registered device. The user views the notification and selects Verify to complete theverification. |
Verification code from mobile app | The Microsoft Authenticator app generates a new OAuth verification code every 30 seconds. The user enters the verificationcode into the sign-in interface. |
The Microsoft Authenticator app helps to prevent unauthorized access to accounts and to stop fraudulent transactions by offering an additional level of security for Azure AD accounts or Microsoft accounts. It can be used either as a second verification method oras a replacement for a password when using phone sign-in. The Authenticator app fully supports both the Verification code and Notification methods of verification in MFA. The Authenticator app is available for Windows phone, Android, and iOS.
Implementing custom multi-factor authentication using .NET
The Multi-Factor Authentication SDK lets you build two-step verification directly into the sign-in or transaction processes of applications in your Azure AD tenant.
The Multi-Factor Authentication SDK is available for C#, Visual Basic (.NET), Java, Perl, PHP, and Ruby. The SDK provides a thin wrapper around two-step verification. It includes everything you need to write your code, including commented source code files, example files, and a detailed ReadMe file. Each SDK also includes a certificate and private key for encrypting transactions that are unique to your MFA provider. As long as you have a provider, you can download the SDK in as many languages and formats asyou need.
Because the APIs do not have access to users registered in Azure AD, you must provide user information in a file or database. Also, the APIs do not provide enrollment or user management features, so you need to build these processes into your application.